Skip to content

Implement UInt64 on top of Int64Native with unsigned ops routed through native layer#12834

Merged
Simn merged 3 commits intohaxe-numericfrom
copilot/sub-pr-12825
Mar 17, 2026
Merged

Implement UInt64 on top of Int64Native with unsigned ops routed through native layer#12834
Simn merged 3 commits intohaxe-numericfrom
copilot/sub-pr-12825

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Mar 17, 2026

Explores whether unsigned 64-bit integers can reuse the same per-target Int64Native implementation as signed Int64, avoiding native code duplication. Answer: yes, with minimal complications.

Design

  • haxe.UInt64abstract UInt64(Int64Native) wrapping the same backing type as Int64
  • Bit-identical ops (add, sub, mul, bitwise, shl) delegate directly to Int64Native
  • Unsigned-specific ops are added to Int64Native itself (udivMod, utoString, uparseString, ufromFloat, utoFloat) on all targets, so native targets can provide optimized implementations in the future. The portable algorithms live in haxe.numeric.UInt64Helper and are used as the default implementation.
  • Comparison uses existing Int64Native.ucompare; >> maps to existing Int64Native.ushr
  • UInt64 has only toString() (no redundant toStr static method)

Key unsigned behaviors

var a = UInt64.make(0x80000000, 0); // 2^63
var b = UInt64.make(0x7FFFFFFF, 0xFFFFFFFF); // 2^63 - 1
trace(a > b); // true (signed Int64 would say false)
trace(Std.string(a)); // "9223372036854775808"

var max = UInt64.make(0xFFFFFFFF, 0xFFFFFFFF);
trace(max >> 4); // logical shift, no sign extension
trace(Std.string(max / 2)); // "9223372036854775807"

Int64 vs UInt64 public interface comparison

Only in Int64: isNeg, ucompare, toStr, isInt64, getHigh/getLow (deprecated), is (deprecated)

Only in UInt64: toFloat, fromInt64, toInt64

Same method, different semantics: compare (signed vs unsigned), toInt (throws vs truncates), toString (signed vs unsigned decimal), parseString/fromFloat (signed vs unsigned range), divMod/div/mod (signed vs unsigned division), shr (>>) (arithmetic vs logical shift)

Identical in both: copy, make, ofInt, isZero, add, sub, mul, eq, neq, and, or, xor, shl, ushr, neg, high/low properties

Files changed

  • std/haxe/UInt64.hx — public abstract with operator overloads, all ops route through Int64Native
  • std/haxe/numeric/UInt64Helper.hx — portable unsigned algorithms (division, toString, parsing, float conversion)
  • std/haxe/numeric/Int64Native.hx — added udivMod, utoString, uparseString, ufromFloat, utoFloat
  • std/jvm/_std/haxe/numeric/Int64Native.hx — added unsigned method signatures (delegates to UInt64Helper)
  • std/hl/_std/haxe/numeric/Int64Native.hx — added unsigned method signatures (delegates to UInt64Helper)
  • std/cpp/_std/haxe/numeric/Int64Native.hx — added unsigned method signatures with CPPIA declarations
  • std/eval/_std/haxe/numeric/Int64Native.hx — added unsigned method signatures (delegates to UInt64Helper)
  • tests/unit/src/unit/TestUInt64.hx — covers construction, unsigned comparison/division/shifts, Int64 round-trips, parsing, edge cases

All unit tests pass on Interp, JS, JVM, Python, Neko, PHP.


🔒 GitHub Advanced Security automatically protects Copilot coding agent pull requests. You can protect all pull requests by enabling Advanced Security for your repositories. Learn more about Advanced Security.

Co-authored-by: Simn <634365+Simn@users.noreply.github.com>
Copilot AI changed the title [WIP] Unify numeric types API across all targets Implement UInt64 on top of Int64Native to validate shared signed/unsigned backing Mar 17, 2026
Copilot AI requested a review from Simn March 17, 2026 12:46
Copilot finished work on behalf of Simn March 17, 2026 12:46
Copy link
Copy Markdown
Member

@Simn Simn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please also compare the Int64 vs. UInt64 public interfaces and let me know the differences.

…ent style

Co-authored-by: Simn <634365+Simn@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Mar 17, 2026

Please also compare the Int64 vs. UInt64 public interfaces and let me know the differences.

Here's the Int64 vs UInt64 public API comparison:

Only in Int64 (not in UInt64):

  • isNeg(x):Bool — not applicable to unsigned
  • ucompare(a, b):Int — UInt64's compare() already does unsigned comparison
  • toStr(x):String — static convenience method (could be removed from Int64 too)
  • isInt64(val:Dynamic):Bool — runtime type check
  • getHigh(x):Int32, getLow(x):Int32 — deprecated (use properties)
  • is(val:Dynamic):Bool — deprecated

Only in UInt64 (not in Int64):

  • toFloat():Float — unsigned float conversion (needed because signed/unsigned differ for high-bit values)
  • fromInt64(x:Int64):UInt64 — reinterpret bits
  • toInt64():Int64 — reinterpret bits

Same method, different semantics:

Method Int64 UInt64
compare() signed unsigned (wraps ucompare)
toInt() throws if out of ±2^31 range returns low 32 bits, no throw
toString() signed decimal (negative prefix) unsigned decimal
parseString() accepts negative strings rejects negative, unsigned overflow detection
fromFloat() accepts negative floats rejects negative floats
divMod()/div()/mod() signed division unsigned division
shr() (>>) arithmetic shift (sign-extends) logical shift (zero-extends, same as >>>)

Identical in both: copy, make, ofInt, isZero, add, sub, mul, eq, neq, and, or, xor, shl, ushr, neg, high/low properties, all comparison operators, all *Int mixed-type overloads.

Possible gaps to discuss:

  • Should UInt64 have isUInt64(val:Dynamic):Bool? (Int64 has isInt64, but they share the same runtime type)
  • Should Int64 also get toFloat/fromInt64?
  • Int64's toInt throws on overflow, UInt64's toInt silently truncates — should they be consistent?

Copilot AI changed the title Implement UInt64 on top of Int64Native to validate shared signed/unsigned backing Implement UInt64 on top of Int64Native with unsigned ops routed through native layer Mar 17, 2026
Copilot AI requested a review from Simn March 17, 2026 13:36
Copilot finished work on behalf of Simn March 17, 2026 13:36
@Simn Simn marked this pull request as ready for review March 17, 2026 14:05
@Simn Simn merged commit f9aad9f into haxe-numeric Mar 17, 2026
61 checks passed
@Simn Simn deleted the copilot/sub-pr-12825 branch March 17, 2026 14:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants